﻿using CDV.IRMS.WebAPI.TaskExecution.Data;
using CDV.IRMS.WebAPI.TaskExecution.Interface;
using CDV.IRMS.WebAPI.TaskExecution.Interface.Impl;
using log4net;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.IO;

namespace CDV.IRMS.WebAPI.TaskExecution.Utils
{
    /// <summary>
    /// 服务注入器
    /// </summary>
    public class ServiceInjector
    {
        /// <summary>
        /// 注入SwaggerAPI文档描述服务
        /// </summary>
        /// <param name="services">Service集合</param>
        public static void InjectSwaggerDoc(IServiceCollection services)
        {
            services.AddSwaggerGen((option) =>
            {
                option.SwaggerDoc("v1",
                    new Swashbuckle.AspNetCore.Swagger.Info()
                    {
                        Version = "v1",
                        Title = "任务执行API",
                        Description = "任务路由执行相关的API接口"
                    });

                //加载注释文档
                var xmlFile = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ".xml";
                var xmlDoc = Path.Combine(AppContext.BaseDirectory, xmlFile);
                if (File.Exists(xmlDoc))
                {
                    option.IncludeXmlComments(xmlDoc);
                }
            });
        }

        /// <summary>
        /// 注入任务管理交互服务
        /// </summary>
        /// <param name="services">Service集合</param>
        /// <param name="configuration">配置对象</param>
        public static void InjectTaskManagerService(IServiceCollection services, IConfiguration configuration)
        {
            //任务管理交互服务接口
            services.AddSingleton<ITaskManagerService, TaskManagerServiceImpl>((sp) =>
            {
                var apiMap = new Dictionary<string, string>()
                {
                    { "QueryTask", configuration.GetValue<string>("Api:TaskManager:RESTfulApi:QueryTask") },
                    { "UpdateRouteStatus", configuration.GetValue<string>("Api:TaskManager:RESTfulApi:UpdateRouteStatus") }
                };

                var timeOut = configuration.GetValue<int>("Api:TaskManager:TimeOut", RESTfulAPI.DefaultTimeout);
                var api = new RESTfulAPI()
                {
                    BaseURL = configuration.GetValue<string>("Api:TaskManager:BaseURL"),
                    TimeOut = new TimeSpan(0, 0, timeOut),
                    APIMap = apiMap
                };
                var taskManagerServiceImpl = new TaskManagerServiceImpl()
                {
                    RESTfulAPI = api
                };

                return taskManagerServiceImpl;
            });
        }

        /// <summary>
        /// 注入矩阵控制服务
        /// </summary>
        /// <param name="services">Service集合</param>
        /// <param name="configuration">配置对象</param>
        public static void InjectMatrixService(IServiceCollection services, IConfiguration configuration)
        {
            //矩阵控制服务接口
            services.AddSingleton<IMatrixControlService, IPMatrixControlServiceImpl>((sp) =>
            {
                var apiMap = new Dictionary<string, string>()
                {
                    { "Take", configuration.GetValue<string>("Api:IPMatrix:RESTfulApi:Take") },
                    { "Lock", configuration.GetValue<string>("Api:IPMatrix:RESTfulApi:Lock") },
                    { "Unlock", configuration.GetValue<string>("Api:IPMatrix:RESTfulApi:Unlock") }
                };

                var timeOut = configuration.GetValue<int>("Api:IPMatrix:TimeOut", RESTfulAPI.DefaultTimeout);
                var api = new RESTfulAPI()
                {
                    BaseURL = configuration.GetValue<string>("Api:IPMatrix:BaseURL"),
                    TimeOut = new TimeSpan(0, 0, timeOut),
                    APIMap = apiMap
                };
                var matrixControlServiceImpl = new IPMatrixControlServiceImpl()
                {
                    RESTfulAPI = api
                };

                return matrixControlServiceImpl;
            });
        }

        /// <summary>
        /// 注入资源管理服务
        /// </summary>
        /// <param name="services">Service集合</param>
        /// <param name="configuration">配置对象</param>
        public static void InjectResourceManageService(IServiceCollection services, IConfiguration configuration)
        {
            //矩阵控制服务接口
            services.AddSingleton<IResourceManagerService, ResourceManagerServiceImpl>((sp) =>
            {
                var apiMap = new Dictionary<string, string>()
                {
                    { "CheckNodeConflict", configuration.GetValue<string>("Api:ResourceManager:RESTfulApi:CheckNodeConflict") }
                };

                var timeOut = configuration.GetValue<int>("Api:ResourceManager:TimeOut", RESTfulAPI.DefaultTimeout);
                var api = new RESTfulAPI()
                {
                    BaseURL = configuration.GetValue<string>("Api:ResourceManager:BaseURL"),
                    TimeOut = new TimeSpan(0, 0, timeOut),
                    APIMap = apiMap
                };
                var resourceManageServiceImpl = new ResourceManagerServiceImpl()
                {
                    RESTfulAPI = api
                };

                return resourceManageServiceImpl;
            });
        }

        /// <summary>
        /// 注入缓存服务
        /// </summary>
        /// <param name="services">Service集合</param>
        public static void InjectCacheService(IServiceCollection services)
        {
            services.AddSingleton<ICacheService, CacheServiceImp>();
        }

        /// <summary>
        /// 注入Log4net
        /// </summary>
        /// <param name="services">Service集合</param>
        public static void InjectLog4net(IServiceCollection services)
        {
            services.AddSingleton<ILog, ILog>((s) =>
            {
                return LogManager.GetLogger(RepositoryName, LogName);
            });
        }

        /// <summary>
        /// Log4net仓储名
        /// </summary>
        public const string RepositoryName = "TaskExecWebApi";

        /// <summary>
        /// Log4net日志名
        /// </summary>
        public const string LogName = "TaskExec";

        /// <summary>
        /// ServiceProvider
        /// </summary>
        public static IServiceProvider ServiceProvider { get; set; }
    }
}
